import math
import re
import os


# 角度转弧度常数
atr = math.pi / 180
# 万有引力常量
ugc = 6.67259 * (math.pow(10, -11))
# 地球质量(从RSS里面测量的)
earth_mass = 5.972 * (math.pow(10, 24))

# KSP RSS 地球同步轨道 42241096m - 6371000m = 对地高度35870096  24h

# 由中心天体计算通信网最小轨道半径
def Orbit_radius_calculation(Re:any, n:int):
    # Re内切圆半径（星球半径），n卫星数
    # 返回最小轨道半径
    Polygonal_angle = ((n-2)*180)/n
    Polygonal_rad = (Polygonal_angle / 2) * atr
    Ro = Re / math.sin(Polygonal_rad)
    return Ro


# 由通信网轨道半径计算中心天体最大半径
def Planet_radius_calculation(Ro:any, n:int):
    # Ro外接圆半径（轨道半径），n卫星数
    # 返回最大星球半径
    Polygonal_angle = ((n-2)*180)/n
    Polygonal_rad = (Polygonal_angle / 2) * atr
    Re = Ro * math.sin(Polygonal_rad)
    return Re


# 运用卫星计算环绕天体质量
def Planet_mass_calculation(Ro:any, Satellite_speed:any):
    # Ro卫星所在轨道半径（不是对地高度），Satellite_speed卫星线速度（轨道速度）
    # 返回中心天体质量
    Satellite_period = (2 * math.pi * Ro) / Satellite_speed
    Planet_mass = (4 * math.pow(math.pi,2) * math.pow(Ro,3)) / (ugc * math.pow(Satellite_period,2))
    return Planet_mass


# 计算构建正多边形通信网的运载火箭的转移轨道
def Transfer_orbit_calculation(Ro:any, n:int, Rp:any, Planet_mass):
    # Ro 通信网卫星所在轨道半径，n通信网卫星数，Rp环绕天体半径，Planet_mass 环绕天体质量，
    # 返回中心天体质量
    gccb = ugc * Planet_mass    # 中心天体引力常数
    Satellite_period = 2 * math.pi * math.pow(math.pow(Ro, 3) / gccb, 0.5)      # 计算通信网轨道的周期
    # print(Satellite_period)
    Transfer_orbital_period = ((n-1) / n) * Satellite_period                    # 计算转移轨道的周期
    # print(Transfer_orbital_period)
    At =math.pow((gccb * math.pow(Transfer_orbital_period, 2)) / (4 * math.pow(math.pi,2)), (1/3))  # 计算转移轨道的半长轴
    # print(At)
    Pe = (2 * At) - Ro  # 计算转移轨道的近地点（Pe）
    # print(Pe)

    # 若Pe小于星球半径，就让运载火箭跑快一点，这样不会掉回大气层
    i = 2
    while (Pe < Rp):
        Transfer_orbital_period = ((n*i-1) / (n*i)) * Satellite_period                    # 计算转移轨道的周期
        # print(Transfer_orbital_period)
        At =math.pow((gccb * math.pow(Transfer_orbital_period, 2)) / (4 * math.pow(math.pi,2)), (1/3))  # 计算转移轨道的半长轴
        Pe = (2 * At) - Ro  # 计算转移轨道的近地点（Pe）
        i = i + 1
        #print("PE%d %f" %(i-2,Pe) )
    
    return Pe, i - 1, At


# 轨道速度计算
def Orbit_speed_calculation(Ao:any, Ro:any, Planet_mass):
    gccb = ugc * Planet_mass
    orbit_speed = math.pow(((2 * gccb) / Ro) - (gccb / Ao) , 0.5)
    return orbit_speed


# 同步轨道计算
def Synchronous_orbit_calculation(Planet_period, Planet_mass):
    # Planet_period 天体自转周期，Planet_mass 环绕天体质量，
    # 返回同步轨道半径
    gccb = ugc * Planet_mass
    Rs = math.pow((gccb * math.pow(Planet_period, 2)) / (4 * math.pow(math.pi, 2)), (1 / 3))
    return Rs


if __name__ == "__main__":
    while(1):
        os.system("cls")
        mode = int(input("选择计算内容。\
                     \n1计算星球质量 \
                     \n2计算正多边形通信网的建立条件\
                     \n3计算同步轨道半径\n"))
        
        if (mode == 1):
            os.system("cls")
            # 星球质量计算
            print("星球质量计算\n\
                  请请使用尽可能接近正圆的轨道进行计算！\n")
            SRo = float(input("请输入环绕卫星的轨道半径（单位m）。\n"))
            Sspeed = float(input("请输入环绕卫星的线速度（单位m/s）。\n"))
            Planet_mass = Planet_mass_calculation(SRo, Sspeed)
            print("当前星球质量为\033[32m %.2f\033[0m  KG" %Planet_mass)

        elif (mode == 2):
            os.system("cls")
            Planet_mass = int(input("请输入要建立通信网的星球的质量（单位KG）。\
                                    \n输入0默认为地球质量。\n"))
            
            
            if (Planet_mass == 0):
                Planet_mass = earth_mass
                Re = 6370000
            else:
                Re = int(input("请输入要建立通信网的星球的半径（单位m）。\n"))

            sputnik_num = int(input("通信网的卫星数。\n"))
            Orbit_radius = Orbit_radius_calculation(Re, sputnik_num)
            
            if (Orbit_radius < 0):
                print("无法建立轨道\n")
            else:
                print("建立轨道的半径应大于\033[32m %.2f\033[0m m\n" %Orbit_radius)
            
            Ro = int(input("请输入要建的立通信网的轨道半径（单位m）。\n"))
            while (Ro < Orbit_radius):
                print("无法建立轨道\n")
                print("建立轨道的半径应大于\033[32m %.2f\033[0m m\n" %Orbit_radius)
                Ro = int(input("请输入要建的立通信网的轨道半径（单位m）。\n"))

            Orbit_radius = Ro
            # Re = Planet_radius_calculation(Orbit_radius, sputnik_num)
            Pe, count, At = Transfer_orbit_calculation(Orbit_radius, sputnik_num, Re, Planet_mass)
            orbit_speed = Orbit_speed_calculation(Orbit_radius, Orbit_radius, Planet_mass)
            Transfer_speed = Orbit_speed_calculation(At, Orbit_radius, Planet_mass)
            dv = orbit_speed - Transfer_speed

            print("转移轨道的PE点地面高度为\033[32m %.2f\033[0m m，轨道半径为\033[32m %.2f\033[0m m。\
                  \n转移轨道的AP点地面高度为\033[32m %.2f\033[0m m，轨道半径为\033[32m %.2f\033[0m m。\
                  \n需要运行\033[32m %d\033[0m 圈才释放一次卫星\n" %(Pe - Re,Pe , Ro - Re,Ro , count))
            print("通信网轨道在与转移轨道的交点时速度为\033[32m %.2f\033[0m m/s\n" %orbit_speed)
            print("转移轨道在与通信网轨道的交点时速度为\033[32m %.2f\033[0m m/s\n" %Transfer_speed)
            print("变轨需要的dv为\033[32m %.2f\033[0m m/s\n" %dv)

        elif (mode == 3):
            os.system("cls")
            Planet_period_str = input("请输入星球的自转周期（格式 DD HH MM SS）。\n")
            Planet_period_str = re.findall(r"\d+\.?\d*", Planet_period_str)

            Planet_period = int(Planet_period_str[0]) * 24 * 3600 + \
                            int(Planet_period_str[1]) * 3600 + \
                            int(Planet_period_str[2]) * 60 + \
                            int(Planet_period_str[3])
            
            Planet_mass = int(input("请输入星球的质量（单位KG）。\
                                    \n输入0默认为地球质量。\n"))
            
            if (Planet_mass == 0):
                Planet_mass = earth_mass

            Rs = Synchronous_orbit_calculation(Planet_period, Planet_mass)

            print("该星球同步轨道半径为\033[32m %.2f\033[0m m" %Rs)
            
        os.system("pause")